/*
 * Copyright (C) 2012 Atlas of Living Australia
 * All Rights Reserved.
 *
 * The contents of this file are subject to the Mozilla Public
 * License Version 1.1 (the "License"); you may not use this file
 * except in compliance with the License. You may obtain a copy of
 * the License at http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * rights and limitations under the License.
 */
package au.org.ala.phylojive
import grails.converters.JSON
import org.apache.commons.io.IOUtils
import org.codehaus.groovy.grails.web.json.JSONObject

import javax.xml.parsers.DocumentBuilderFactory

class ProxyController {
    def webService
    def batchSize = 100

    def getCharacters() {
        def names = params.names.replaceAll(" ", "+")
        def dataset = params.dataset
        def url = grailsApplication.config.identifyLifeUrl + "?t=" + names + "&d=" + dataset
        def json = webService.get(url)
        def jsonObj = JSON.parse(json.toString())
        log.debug "jsonObj type = " + jsonObj.getClass()

        if (jsonObj instanceof JSONObject && true && jsonObj.has("error")) {
            log.debug "json = " + json
            //response.status = 500
            //render (contentType: "application/json", text: json)
            render(status: 500, text: jsonObj.error)
        } else if (params.callback) {
            render (contentType: "application/javascript", text: "${params.callback}(${json})")
        } else {
            render (contentType: "application/json", text: json)
        }
    }

    /**
     * Sends batched-up requests to Identify Life, so as to overcome limits of long GET URLs
     *
     * @return
     */
    def getCharactersPost() {
        def names = params.names?.replaceAll(" ", "+")
        def dataset = params.dataset
        def namesList = names?.split(";") as List
        def pagedNames = namesList.collate(batchSize) // batch up
        def jsonResult = new JSONObject() // batched results get added to this

        pagedNames.eachWithIndex { group, i ->
            //log.debug i + " paging taxa..." + group.size()
            def url = grailsApplication.config.identifyLifeUrl + "?t=" + group.join(";") + "&d=" + dataset
            def jsonObj = JSON.parse(webService.get(url))

            jsonObj.each {
                // add to jsonResult
                jsonResult.put(it.key, it.value);
            }
        }

        render (contentType: "application/json", text: jsonResult.toString())
    }
    /**
     * sends a proxy request using url as the target page
     *
     * @return
     */
    def getPage() {
        def url = URLDecoder.decode( params.url )
//        def dataset = params.dataset
//        def url = grailsApplication.config.identifyLifeUrl + "?t=" + names + "&d=" + dataset
        def json = webService.get(url)
//        def jsonObj = JSON.parse(json.toString())
        log.debug "jsonObj type = " + url

//        if (jsonObj instanceof JSONObject && true && jsonObj.has("error")) {
//            log.debug "json = " + json
//            //response.status = 500
//            //render (contentType: "application/json", text: json)
//            render(status: 500, text: jsonObj.error)
//        } else
        if (params.callback) {
            render (contentType: "application/javascript", text: "${params.callback}('${json}')")
        } else {
            render (contentType: "text/plain", text: json)
        }
    }

    /**
     * sends a proxy request using url as the target page
     *
     * @return
     */
    def searchTreebase() {
//        def url = URLDecoder.decode( params.url )
////        def dataset = params.dataset
////        def url = grailsApplication.config.identifyLifeUrl + "?t=" + names + "&d=" + dataset
        def query = params.q;
        query = query.replace(' ','%20');
        def json = [], id
        //println("http://treebase.org/treebase-web/phylows/study/find?format=rss1&recordSchema=tree&query=dcterms.title=%22${query}%22 or dcterms.contributor=%22${query}%22")
//        def urlStr = "http://treebase.org/treebase-web/phylows/study/find?format=rss1&recordSchema=tree&query=dcterms.title=\"${query}\" or dcterms.contributor=\"${query}\"";
        def urlStr = "http://treebase.org/treebase-web/phylows/study/find?format=rss1&recordSchema=tree&query=dcterms.title==\"${query}\"";
        URL url = new URL(urlStr);
        URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
        urlStr = uri.toURL().toString();
        println( urlStr )
//        urlStr = "http://treebase.org/treebase-web/phylows/study/find?format=rss1\\&recordSchema=tree\\&query=%28tb.title.study+%3D+Miller%29+or+%28dcterms.contributor+%3D+Miller%29"
        def rss = webService.get( urlStr );
        System.out.println( rss );
        if( rss ){
            def df = DocumentBuilderFactory.newInstance();
            def builder =  df.newDocumentBuilder()
            try{
//                def json = new groovy.json.JsonBuilder();

//                def link = {}
                def rsser = builder.parse( IOUtils.toInputStream( rss,'UTF-8' ) )
                def nodelist = rsser.getElementsByTagName('item');
                println("getting a lot of names")
                Iterator iter = nodelist.iterator();
                def cIter;
                while(iter.hasNext()){
//                    def link = new groovy.json.JsonBuilder()
                    def link = [:];
                    Object item = iter.next();
                    def children = item.childNodes;
                    cIter = children.iterator();
                    while( cIter.hasNext() ){
                        def child = cIter.next();
//                        println ( child.getNodeName() );
                        switch ( child.getNodeName() ){
                            case 'description':
//                                println ( child.getTextContent() )
//                                link id: child.getTextContent()
//                                link.properties['id'] = child.getTextContent()
//                                link.put('id', child.getTextContent());
                            id = child.getTextContent()
                            link.id = id.replaceFirst('TB2:','')
                                break;
                            case 'title':
//                                link['title'] = child.getNodeValue();
                                link.title = child.getTextContent()
                                break;
                        }

                    }
//                    println( link.toString() )
                    json.push( link );
                }
            } catch (Exception e ){
                return "NEXML is not well formed"
            }

        }
//        Collection items = rss.getChannel().getItems();
////        def jsonObj = JSON.parse(json.toString())
//        log.debug "jsonObj type = " + url
        json = new groovy.json.JsonBuilder( json );
        json = json.toString();
        if (params.callback) {
            render (contentType: "application/javascript", text: "${params.callback}("+json+")")
        } else {
            render (contentType: "application/json", text: json)
        }
    }
}